package main

import "fmt"

func main() {
	// Go语言中无缓冲的通道（unbuffered channel）是指在接收前没有能力保存任何值的通道。
	// 这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好，才能完成发送和接收操作

	// Go语言中有缓冲的通道（buffered channel）是一种在被接收前能存储一个或者多个值的通道。
	// 这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。
	// 通道会阻塞发送和接收动作的条件也会不同。只有在通道中没有要接收的值时，接收动作才会阻塞。
	// 只有在通道没有可用缓冲区容纳被发送的值时，发送动作才会阻塞。

	// 这导致有缓冲的通道和无缓冲的通道之间的一个很大的不同：
	// 无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换；
	// 有缓冲的通道没有这种保证

	// 创建一个3个元素缓冲大小的整型通道
	ch := make(chan int, 3)
	// 查看当前通道的大小
	fmt.Println(len(ch))
	// 发送3个整型元素到通道
	ch <- 1
	ch <- 2
	ch <- 3
	close(ch)
	// 查看当前通道的大小
	fmt.Println(len(ch))
	for info := range ch {
		fmt.Println("info is ", info)
	}
	fmt.Println("ending")
}
// 阻塞条件
// 带缓冲通道在很多特性上和无缓冲通道是类似的。无缓冲通道可以看作是长度永远为 0 的带缓冲通道。
// 因此根据这个特性，带缓冲通道在下面列举的情况下依然会发生阻塞：

// 带缓冲通道被填满时，尝试再次发送数据时发生阻塞。
// 带缓冲通道为空时，尝试接收数据时发生阻塞。
// 为什么Go语言对通道要限制长度而不提供无限长度的通道？
// 我们知道通道（channel）是在两个 goroutine 间通信的桥梁。
// 使用 goroutine 的代码必然有一方提供数据，一方消费数据。
// 当提供数据一方的数据供给速度大于消费方的数据处理速度时，
// 如果通道不限制长度，那么内存将不断膨胀直到应用崩溃。
// 因此，限制通道的长度有利于约束数据提供方的供给速度，
// 供给数据量必须在消费方处理量+通道长度的范围内，才能正常地处理数据。